<?php

App::uses('Crud', 'Model');
App::uses('Asociado', 'Model');
App::uses('Category', 'Model');
App::uses('Line', 'Model');
App::uses('Workstation', 'Model');
App::uses('ShiftModel', 'Model');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');

class User extends Crud {

    const STATUS_ENABLED = 1;
    const STATUS_INCAPACIDAD = 2;
    const STATUS_DISABLED = 0;
    const STATUS_VACACIONES = 3;
    const SUPPORT_ON = 1;
    const SUPPORT_OFF = 0;
    const EXTERNAL_ON = 1;
    const EXTERNAL_OFF = 0;
    const STR_ASSOCIATED = 'Asociado';
    public $useTable = 'us3rs_r4gg14n4';
    public $validate = array(
        'us3r' => array(
            'required' => array(
                'rule' => 'alphaNumeric',
                'message' => 'Usuario es requerido'),
    ));

    public function getByUsernameAndPass($username, $pass) {
        $passwordHasher = new SimplePasswordHasher();
        $pass = $passwordHasher->hash($pass);
        $users = $this->findByUs3rAndP4ssAndStatus($username, $pass, Usuario::STATUS_ENABLED);
        return count($users) > 0 ? $users[0] : null;
    }

    public function beforeSave($options = array()) {
        if (isset($this->data['User']['p4ss']) === true) {
            $passwordHasher = new SimplePasswordHasher();
            $this->data['User']['p4ss'] = $passwordHasher->hash($this->data['User']['p4ss']);
        }
    }

    public function changePass($id, $newPass) {
        $passwordHasher = new SimplePasswordHasher();
        $newPass = $passwordHasher->hash($newPass);
        $db = $this->getDataSource();
        $db->fetchAll("UPDATE us3rs_r4gg14n4 SET p4ss = ? WHERE id = ?", array(
            $newPass, $id));
    }

    /**
     * Obtenemos los registros habilitados.
     * @return array
     */
    public function getEnabled() {
        $order = array('name' => 'ASC');
        $records = $this->findAllByStatus(self::STATUS_ENABLED, array(), $order);
        return $this->flatArray($records);
    }

    public function getEnabledForGrid() {
        $filters = array(
            'fields' => array(
                'full_name as text',
                'id as value'
            ),
            'conditions' => array(
                'status !=' => self::STATUS_DISABLED
            ),
            'order' => array('name' => 'ASC')
        );
        $records = $this->find('all', $filters);
        return $this->flatArray($records);
    }

    public function getDisabled() {
        $order = array('name' => 'ASC');
        $records = $this->findAllByStatus(self::STATUS_DISABLED, array(), $order);
        return $this->flatArray($records);
    }

    public function getAll() {
        $filters = array(
            'order' => array('admission_date' => 'ASC'),
            'conditions' => array('NOT' => array('status' => self::STATUS_DISABLED))
        );
        $records = $this->find('all', $filters);
        return $this->flatArray($records);
    }

    public function getByCategory($category) {
        $categories = Category::getCategories($category);
        $types = self::getPublicStatus($category);
        $tps = Set::classicExtract($types, '{n}.value');
        $cats = Set::classicExtract($categories, '{n}.value');
        $filters = array(
            'order' => array('admission_date' => 'ASC'),
            'conditions' => array(
                'status' => $tps,
                'category_id' => $cats,
            ),
        );
        $records = $this->find('all', $filters);
        return $this->flatArray($records);
    }

    public static function getPublicStatus($category)
    {
        $categories = array();
        switch ($category) {
            case Category::KAOISAMA:
                $categories = array(
                    array('text' => __('Activo'), 'value' => self::STATUS_ENABLED),
                    array('text' => __('Incapacidad'), 'value' => self::STATUS_INCAPACIDAD),
                    array('text' => __('Vacaciones'), 'value' => self::STATUS_VACACIONES),
                    array('text' => __('Inactivo'), 'value' => self::STATUS_DISABLED),
                );
                break;
            case Category::ADMIN:
                $categories = array(
                    array('text' => __('Activo'), 'value' => self::STATUS_ENABLED),
                    array('text' => __('Incapacidad'), 'value' => self::STATUS_INCAPACIDAD),
                    array('text' => __('Vacaciones'), 'value' => self::STATUS_VACACIONES),
                    array('text' => __('Inactivo'), 'value' => self::STATUS_DISABLED),
                );
                break;
            case Category::SUPERVISOR:
                $categories = array(
                    array('text' => __('Activo'), 'value' => self::STATUS_ENABLED),
                    array('text' => __('Incapacidad'), 'value' => self::STATUS_INCAPACIDAD),
                    array('text' => __('Vacaciones'), 'value' => self::STATUS_VACACIONES),
                );
                break;
            case Category::FACILITADOR:
                $categories = array(
                    array('text' => __('Activo'), 'value' => self::STATUS_ENABLED),
                );
                break;
        }
        return $categories;
    }

    /**
     * Obtenemos los usuarios para la matriz e habilidades
     * @param type $userId
     * @return type
     */
    public function getUserForMH($userId) {
        $filters = array(
            'conditions' => array(
                'status' => self::STATUS_ENABLED,
                'OR' => array(
                    'id' => $userId,
                    'preparador_id' => $userId
                ),
            ),
        );
        $records = $this->find('all', $filters);
        return $records;
    }

    public function deleteAsociados() {
        $conditions = array(
            'category_id' => 'aa0ac014-02c0-11e4-995e-24b6fdfa405b',
        );
        $this->deleteAll($conditions, false);
    }

    /**
     * Buscamos los usuarios que coincidan con la semilla
     * @param string $seed UUID
     * @return array
     */
    public function getForFilter($seed) {
        $filters = array();
        try {
            $date = new DateTime($seed);
            $filters = array(
                'conditions' => array(
                    'admission_date' => $date->format('Y-m-d'),
                ),
            );
        } catch (Exception $exc) {
            $filters = array(
                'fields' => array(
                    'id',
                    'full_name',
                    'curp',
                    'nomina',
                    'admission_date',
                ),
                'conditions' => array(
                    'category_id' => 'aa0ac014-02c0-11e4-995e-24b6fdfa405b',
                    'OR' => array(
                        'nomina LIKE' => "%" . $seed . "%",
                        'full_name LIKE' => "%" . $seed . "%",
                        'curp LIKE' => "%" . $seed . "%",
                    )
                ),
            );
        }
        return $this->flatArray($this->find('all', $filters));
    }

    public function getByNomina($nomina) {
        $filters = array(
            'conditions' => array(
                'nomina' => $nomina,
            ),
        );
        return $this->find('first', $filters);
    }

    public function getByCURP($curp) {
        $filters = array(
            'conditions' => array(
                'curp' => $curp,
            ),
        );
        return $this->find('first', $filters);
    }
    
    public function getAssociatedByNomina($nomina) {
        $filters = array(
            'conditions' => array(
                'nomina' => $nomina,
            ),
            'joins' => array(
                array(
                    'table' => 'categories',
                    'alias' => 'c',
                    'type' => 'inner',
                    'conditions' => array(
                        'c.id = User.category_id',
                        'c.name' => self::STR_ASSOCIATED,
                    ),
                )
            ),
        );
        return $this->find('first', $filters);
    }

    public function getEnabledShortDesciption($category) {
        $categories = Category::getCategories($category);
        $types = self::getPublicStatus($category);
        $tps = Set::classicExtract($types, '{n}.value');
        $cats = Set::classicExtract($categories, '{n}.value');
        $filters = array(
            'fields' => array(
                'id',
                'nomina as nom',
                'curp as c',
                'category_id as cId',
                'full_name as fn',
                'name as n',
                'last_name_1 as ln1',
                'last_name_2 as ln2',
                'status',
                'admission_date as ad',
                'support as sup',
                'is_external as ie',
            ),
            'order' => array('admission_date' => 'ASC'),
            'conditions' => array(
                'status' => $tps,
                'category_id' => $cats,
            ),
        );
        $records = $this->find('all', $filters);
        return $this->flatArray($records);
    }

//    public function getUsersForShiftModel($startDate, $endDate) {
//        $status = array(
//            self::STATUS_ENABLED,
//            self::STATUS_INCAPACIDAD,
//            self::STATUS_VACACIONES,
//        );
//        $types = array(
//            Category::ASOCIADO,
//        );
//        $filters = array(
//            'fields' => array(
//                'id',
//                'nomina as nom',
//                'curp as c',
//                'category_id as cId',
//                'full_name as fn',
//                'name as n',
//                'last_name_1 as ln1',
//                'last_name_2 as ln2',
//                'status',
//                'admission_date as ad',
//                'support as sup',
//                'is_external as ie',
//            ),
//            'joins' => array(
//                array(
//                    'table' => 'shift_models',
//                    'alias' => 'sm',
//                    'type' => 'left',
//                    'conditions' => array(
//                        'sm.user_id = User.id',
//                        'sm.status' => ShiftModel::STATUS_ENABLED,
//                        'sm.work_date >=' => $startDate,
//                        'sm.work_date <=' => $endDate,
//                    ),
//                )
//            ),
//            'conditions' => array(
//                'status' => $status,
//                'category_id' => $types,
//            ),
//        );
//        $records = $this->find('all', $filters);
//        return $this->flatArray($records);
//    }

    public function getMhByUser($userId, $lineId) {
        $filters = array(
            'fields' => array(
                'User.id as userId',
                'User.full_name as userName',
                'User.nomina',
                'ul.level',
                'w.id as workstationId',
                'w.name as workstationName',
                'w.notification_end as workstationNotificationDays',
                'w.optional as workstationOptional',
                'c.id as certificationId',
                'c.start as certificationStart',
                'c.end as certificationEnd',
                'c.life as certificationLife',
                'c.success as certificationSuccess',
                'ul.certifications as nCertifications',
                'c.training as certificationTraining',
                'c.lock as certificationLock',
                'c.lock_date as certificationLockDate',
                'cc.colour',
                'cc.icon',
                'c.status as certificationStatus'
            ),
            'joins' => array(
                array(
                    'table' => 'user_lines',
                    'alias' => 'ul',
                    'type' => 'INNER',
                    'conditions' => array(
                        'ul.user_id' => $userId,
                        'ul.line_id' => $lineId,
                    ),
                ),
                array(
                    'table' => 'categorizations',
                    'alias' => 'cc',
                    'type' => 'INNER',
                    'conditions' => array(
                        'cc.line_id = ul.line_id',
                        'cc.id = ul.level',
                    ),
                ),
                array(
                    'table' => 'workstations',
                    'alias' => 'w',
                    'type' => 'INNER',
                    'conditions' => array(
                        'w.line_id' => $lineId,
                        'w.status' => Workstation::STATUS_ENABLED,
                    ),
                ),
                array(
                    'table' => 'certifications',
                    'alias' => 'c',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'c.workstation_id = w.id',
                        'c.user_id = User.id',
                        'c.status' => Certification::STATUS_ENABLED,
                    ),
                ),
            ),
            'conditions' => array(
                'User.id' => $userId,
            ),
        );
        return $this->flatArray($this->find('all', $filters));
    }

    public function getEnabledForManagers() {
        $filters = array(
            'fields' => array(
                'User.id as value',
                'User.full_name as text'
            ),
            'joins' => array(
                array(
                    'table' => 'categories',
                    'alias' => 'c',
                    'type' => 'INNER',
                    'conditions' => array(
                        'User.category_id = c.id',
                        'c.status' => Category::STATUS_ACTIVE
                    ),
                )
            ),
            'conditions' => array(
                'User.status' => self::STATUS_ENABLED,
                'c.name != "Asociado"'
            )
        );

        return $this->flatArray($this->find('all', $filters));
    }

    public function getEnabledByNominaIfA($nomina, $scheduleId) {
        $filters = array(
            'fields' => array(
                'User.id as value'
            ),
            'joins' => array(
                array(
                    'table' => 'categories',
                    'alias' => 'c',
                    'type' => 'INNER',
                    'conditions' => array(
                        'User.category_id = c.id',
                        'c.status' => Category::STATUS_ACTIVE
                    ),
                ),
                array(
                    'table' => 'user_tests',
                    'alias' => 'ut',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'ut.user_id = User.id',
                        'ut.schedule_id' => $scheduleId,
                        'ut.status' => UserTest::STATUS_ENABLED
                    ),
                )
            ),
            'conditions' => array(
                'User.nomina' => $nomina,
                'c.id' => Category::ASOCIADO,
                'ut.id is NULL',
                'User.status' => self::STATUS_ENABLED
            )
        );

        return $this->find('first', $filters);
    }

    public function getUsersForShiftModelWeek($startDate)
    {
        $endDate = new DateTime($startDate->format('Y-m-d'));
        $endDate->modify('+7 days');
        $status = array(
            User::STATUS_ENABLED,
            User::STATUS_INCAPACIDAD,
            User::STATUS_VACACIONES,
        );
        $categories = array(
            Category::ASOCIADO,
        );
        $filters = array(
            'fields' => array(
                'User.nomina as nom',
                'sm.shift_id as s',
                'sm.assist_id as a',
                'sm.line_id as l',
                'sm.work_date as wd',
                'l.colour as lc',
            ),
            'joins' => array(
                array(
                    'table' => 'shift_models',
                    'alias' => 'sm',
                    'type' => 'left',
                    'conditions' => array(
                        'sm.user_id = User.id',
                        'sm.work_date >=' => $startDate->format('Y-m-d'),
                        'sm.work_date <=' => $endDate->format('Y-m-d'),
                    ),
                ),
                array(
                    'table' => 'lines',
                    'alias' => 'l',
                    'type' => 'left',
                    'conditions' => array(
                        'sm.line_id = l.id',
                    ),
                ),
            ),
            'conditions' => array(
                'User.category_id' => $categories,
                'User.status' => $status,
            ),
            'order' => array(
                'User.nomina ASC',
                'sm.work_date ASC'
            ),
        );
        $records = $this->find('all', $filters);
        return $this->flatArray($records);
    }

    public function getUsersForShiftModel($startDate)
    {
        $status = array(
            User::STATUS_ENABLED,
            User::STATUS_INCAPACIDAD,
            User::STATUS_VACACIONES,
        );
        $categories = array(
            Category::ASOCIADO,
        );
        $filters = array(
            'fields' => array(
                'sm.id',
                'sm.work_date as wd',
                'User.id as u',
                'User.nomina as nom',
                'User.curp as curp',
                'User.full_name',
                'sm.shift_id as s',
                'sm.assist_id as a',
                'sm.line_id as l',
                'l.colour as lc',
            ),
            'joins' => array(
                array(
                    'table' => 'shift_models',
                    'alias' => 'sm',
                    'type' => 'left',
                    'conditions' => array(
                        'sm.user_id = User.id',
                        'sm.work_date =' => $startDate,
                    ),
                ),
                array(
                    'table' => 'lines',
                    'alias' => 'l',
                    'type' => 'left',
                    'conditions' => array(
                        'sm.line_id = l.id',
                    ),
                ),
            ),
            'conditions' => array(
                'User.category_id' => $categories,
                'User.status' => $status,
            ),
            'order' => array(
                'User.nomina ASC',
            ),
        );
        $records = $this->find('all', $filters);
        return $this->flatArray($records);
    }

    /**
     * Obtenemos el numero total de asociados
     * @return integeer
     */
    public function getTotalAsociates()
    {
        $status = array(
            User::STATUS_ENABLED,
            User::STATUS_INCAPACIDAD,
            User::STATUS_VACACIONES,
        );
        $categories = array(
            Category::ASOCIADO,
        );
        $filters = array(
            'conditions' => array(
                'User.category_id' => $categories,
                'User.status' => $status,
            ),
        );
        return $this->find('count', $filters);
    }
}
